package com.yehongyu.mytools.dom.xml;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Attribute;
import org.jdom.Comment;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Text;
import org.jdom.input.SAXBuilder;

/**
 * 根据传入的参数获取JDom的Document对象
 * @author yingyang
 * @since 2011-11-29
 */
public class JDomReader {
	
	private static SAXBuilder builder = new SAXBuilder();

	private static Log log = LogFactory.getLog(JDomReader.class);

	/**
	 * 根据文件名解析对应的文件
	 * @param fileName 指定的文件名
	 * @return 解析后的Document对象
	 */
	public static Document getDocument(String fileName){
		if (fileName == null) {
			log.error("指定的文件名为空");
			return null;
		}
		log.debug("Try to find file <" + fileName + ">");
		File file = new File(fileName);
		if (file.exists()) {
			return getDocument(file);
		}
		log.debug("Try to treat fileName <" + fileName + "> as URL");
		URL fileUrl = Thread.currentThread().getContextClassLoader()
				.getResource(fileName);
		if (fileUrl == null) {
			log.error("找不到指定的文件<" + fileName + ">");
			return null;
		}
		return getDocument(fileUrl);
	}

	/**
	 * 解析指定URL的文件
	 * @param fileUrl 指定的文件的URL
	 * @return 解析后的Document对象
	 */
	public static Document getDocument(URL fileUrl){
		if (fileUrl == null) {
			log.error("没有指定URL");
			return null;
		}
		try {
			return builder.build(fileUrl);
		} catch (JDOMException e) {
			log.error("DOM文件解析出错",e);
		} catch (IOException e) {
			log.error("DOM文件IO出错",e);
		}
		return null;
	}

	/**
	 * 解析指定的文件，并返回对应的Document对象
	 * @param file 指定的文件
	 * @return 获取的Document对象
	 */
	public static Document getDocument(File file){
		if (file == null) {
			log.error("没有指定文件");
			return null;
		}
		try {
			return builder.build(file);
		} catch (JDOMException e) {
			log.error("DOM文件解析出错",e);
		} catch (IOException e) {
			log.error("DOM文件IO出错",e);
		}
		return null;
	}

	/**
	 * 根据XML文件的内容解析出一个Document对象
	 * @param content XML文件的内容
	 * @return 解析后的Document对象
	 * @throws Exception xml内容为空或者解析失败
	 */
	public static Document getDocumentByContent(String content){
		if (content == null) {
			log.error("指定的XML文件内容为空");
			return null;
		}
		try {
			StringReader reader = new StringReader(content);
			return builder.build(reader);
		} catch (JDOMException e) {
			log.error("DOM文件解析出错",e);
		} catch (IOException e) {
			log.error("DOM文件IO出错",e);
		}
		return null;
	}
	
	/**
	 * 递归输出DOM元素
	 * @param e
	 * @return
	 */
	public static StringBuffer getElementStr(Element e){
		StringBuffer sb = new StringBuffer();
		if(e!=null) sb.append("<").append(e.getName());
		if(e.getAttributes()!=null&&e.getAttributes().size()>0){
			@SuppressWarnings("unchecked")
			List<Attribute> as = (List<Attribute>)e.getAttributes();
			for(Attribute a:as){
				sb.append(" ").append(a.getName()).append("=\"").append(a.getValue()).append("\"");
			}
		}
		if(e.getContentSize()==0){
			sb.append("/>");
		}else{
			sb.append(">");
			List<?> cList = e.getContent();
			for(Object c:cList){
				if(c instanceof Text){
					sb.append(((Text)c).getText());
				}else if(c instanceof Element){
					sb.append(getElementStr(((Element)c)));
				}else if(c instanceof Comment){
					sb.append("<!--").append(((Comment)c).getText()).append("-->");
				}
			}
			sb.append("</").append(e.getName()).append(">");
		}
		return sb;
	}
	
	public static void main(String[] args){
		
		Document dom = JDomReader.getDocument(ClassLoader.getSystemResource("dom/Input.xml").getFile());
		System.out.println("DOM文档对象:\r\n" + JDomReader.getElementStr(dom.getRootElement()));	//DOM文档对象
		System.out.println("DOM文档地址:" + dom.getBaseURI());	//DOM文档地址
		System.out.println("DOM节点个数:" + dom.getContentSize());	//DOM节点个数
		System.out.println("DOM节点内容:" + ((Element)dom.getRootElement().getChildren().get(0)).getContent());	//DOM节点内容
		System.out.println("DOM文档类型:" + dom.getDocType());
		System.out.println("DOM父对象:" + dom.getParent());
		System.out.println("DOM根节点:" + dom.getRootElement());
		System.out.println("DOM***:" + dom.getRootElement().getContentSize());
		System.out.println("DOM***:" + dom.getRootElement().getName());
		System.out.println("DOM***:" + dom.getRootElement().getNamespacePrefix());
		System.out.println("DOM***:" + dom.getRootElement().getNamespaceURI());
		System.out.println("DOM***:" + dom.getRootElement().getQualifiedName());
		System.out.println("DOM***:" + dom.getRootElement().getText());
		System.out.println("DOM***:" + dom.getRootElement().getTextNormalize());
		System.out.println("DOM***:" + dom.getRootElement().getTextTrim());
		System.out.println("DOM***:" + dom.getRootElement().getValue());
		System.out.println("DOM***:" + dom.getRootElement().getAdditionalNamespaces());
		System.out.println("DOM***:" + dom.getRootElement().getAttributes());
		System.out.println("DOM***:" + dom.getRootElement().getChildren());
		System.out.println("DOM***:" + dom.getRootElement().getContent());
		System.out.println("DOM***:" + dom.getRootElement().getDescendants());
		System.out.println("DOM***:" + dom.getRootElement().getDocument());
		System.out.println("DOM***:" + dom.getRootElement().getNamespace());
		System.out.println("DOM***:" + dom.getRootElement().getParent());
		System.out.println("DOM***:" + dom.getRootElement().getParentElement());
		System.out.println("DOM***:" + dom.getRootElement().isRootElement());

		//获取auto-config的XML配置项默认值定义
		/*System.out.println("Start====================");
		long t = System.currentTimeMillis();
		Document dom = JDom.getDocument("D:/dev/newwork/ie/common/config/src/main/resources/META-INF/autoconf/auto-config.xml");
		System.out.println("atime:"+(System.currentTimeMillis()-t));
		t = System.currentTimeMillis();
		@SuppressWarnings("unchecked")
		List<Element> eList = dom.getRootElement().getChild("group").getChildren("property");
		System.out.println("atime:"+(System.currentTimeMillis()-t));
		t = System.currentTimeMillis();
		Set<String> pNames = new LinkedHashSet<String>();
		System.out.println("atime:"+(System.currentTimeMillis()-t));
		t = System.currentTimeMillis();
		//以下三种写法，似乎时间差不多
		for(Element e:eList){
			pNames.add(e.getAttributeValue("name"));
		}
		for(int i=0;i<eList.size();i++){
			pNames.add(((Element)eList.get(i)).getAttributeValue("name"));
		}
		Iterator<?> it = eList.iterator();
		while(it.hasNext()){
			pNames.add(((Element)it.next()).getAttributeValue("name"));
		}
//		System.out.println(pNames.size());
		System.out.println("atime:"+(t=(System.currentTimeMillis()-t)));*/
		
		//获取用户目录下antx配置项
		/*System.out.println("====================");
		Map<String,String> antx = new HashMap<String,String>();
		try{
			BufferedReader in = new BufferedReader(new FileReader("C:/Documents and Settings/yingyang/antx.properties"));
			String linestr;
			int line =0;
			String key,value;
			while((linestr=in.readLine())!=null){
				if(StringUtils.isBlank(linestr)) continue;
				int idx = linestr.indexOf("=");
				if(idx>=0){
					key = linestr.substring(0,idx).trim();
					value = linestr.substring(idx+1).trim();
//					System.out.println(key+"="+value);
					antx.put(key, value);
					line++;
				}
			}
			System.out.println(line);
		} catch (FileNotFoundException e) {
			log.error("FileNotFoundException error", e);
		} catch (IOException e) {
			log.error("IOException error", e);
		}*/
		
		/*//根据Auto-config配置找到配置项的值
		System.out.println("====================");
		for(String p:pNames){
			System.out.println(p+"="+antx.get(p));
		}*/
		
		

		//打印去除空格后的配置项
		/*System.out.println("====================");
		Map<String,String> antxme = new HashMap<String,String>();
		try{
			BufferedReader in = new BufferedReader(new FileReader("d:/dev/newwork/iesearch/antxme.properties"));
			String linestr;
			int line =0;
			String key,value;
			while((linestr=in.readLine())!=null){
				if(StringUtils.isBlank(linestr)) continue;
				int idx = linestr.indexOf("=");
				if(idx>=0){
					key = linestr.substring(0,idx).trim();
					value = linestr.substring(idx+1).trim();
					System.out.println(key+"="+value);
					antxme.put(key, value);
					line++;
				}
			}
			System.out.println(line);
		} catch (FileNotFoundException e) {
			log.error("FileNotFoundException error", e);
		} catch (IOException e) {
			log.error("IOException error", e);
		}*/
	}
}